package com.fingard.dsp.bank.directbank.wfccb01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.math.BigDecimal;
import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;


/**
 * 潍坊银行单笔付款查询
 * Created by F on 2019/06/17.
 */
public class WFCCB01SinglePay extends WFCCB01Base implements ISinglePay {
    /**
     * 支付
     * @param p_req1908
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAtsSingle = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        Connection conn= FGBiz.getLocalDbConn();
        try{
            //======拼接报文======
            //拼接请求报文体
            WFCCB01Header header = new WFCCB01Header();
            if("1".equals(p_req1908.singleDetail.sameBnk)){//同行
                header.opname="enterpriseAccPay";
            }else if("0".equals(p_req1908.singleDetail.sameBnk)){//他行
                header.opname="otherAccPay";
            }
            header.serialNo = getQryTransID();
            XmlTextWriter xmlReq = new XmlTextWriter();
            writeReqHeader(xmlReq,header);
            XElement body =new XElement("ReqParam","");
            body.addChild(new XElement("payAccount",p_req1908.singleDetail.payAct));//付款账号
            body.addChild(new XElement("payAccountName",p_req1908.singleDetail.payName));//付款人名称
            body.addChild(new XElement("recAccount",p_req1908.singleDetail.recAct));//收款账号
            body.addChild(new XElement("recAccountName",p_req1908.singleDetail.recName));//收款人名称
            body.addChild(new XElement("payAmount",p_req1908.singleDetail.payAmount));//付款金额
            body.addChild(new XElement("currencyType",convertCurToBank(p_req1908.singleDetail.payCur)));//付款币种
            body.addChild(new XElement("orderFlowNo",header.serialNo));//付款流水号
            //记录ats支付流水号对应的银行支付流水号，供查询状态接口使用
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.singleDetail.askNumber, header.serialNo});
            body.addChild(new XElement("payUse",p_req1908.singleDetail.purpose));//用途
            body.addChild(new XElement("trsDateTime",DateHelper.convertD10toD8(p_req1908.singleDetail.payDate)
                    +p_req1908.singleDetail.payTime.replaceAll(":","")));//付款时间yyyyMMddHHmmss
            if("0".equals(p_req1908.singleDetail.sameBnk)){
                String remRoute="7";
                String urgentFlag = getBankConfig().getValueAsString("UrgentLargeAmount");
                if (StringHelper.hasAnyChar(urgentFlag)) {
                    if ((new BigDecimal(p_req1908.singleDetail.payAmount)).compareTo(new BigDecimal(urgentFlag)) >= 0) {
                        remRoute = "5";
                    }
                }
                body.addChild(new XElement("remRoute",remRoute));//5：大额 7：小额
                body.addChild(new XElement("recAccountOpenBank",p_req1908.singleDetail.cnapsCode));//收款方行号
                body.addChild(new XElement("recAccountOpenBankName",p_req1908.singleDetail.cnapsName));//收款方行名
            }
            nodeAnalysis(p_req1908.singleDetail.srcXElement,body,getCharset());
            xmlReq.writeXElement(body);
            xmlReq.writeEndDocument();
            //获取签名数据
            String sign=signnatrue(xmlReq.toXmlString());
            //拼接请求报文
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            header.signedData=sign;
            writeCommonHeader(xmlTextWriter,header);
            xmlTextWriter.directWrite(xmlReq.toXmlString());
            xmlTextWriter.writeEndElement();
            //======拼接报文======
            //发送请求报文
            String[] bankResult = sendToBank(requestBody(header,xmlTextWriter.toXmlString()));
            //处理响应报文
            if(bankResult[0].length()==0){
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                if(tmpBkReader!=null){
                    String respCode = tmpBkReader.getFirstText("/BankData/opRep/hostReturnCode");
                    String respInfo = tmpBkReader.getFirstText("/BankData/opRep/hostErrorMessage");
                    detail.respCode = "0";
                    detail.respInfo = respCode+" "+respInfo;
                    detail.reqSeqID = p_req1908.singleDetail.askNumber;
                    //hostReturnCode全为0表示成功
                    //hostReturnCode全为9表示交易超时，交易结果需通过交易结果查询接口查询
                    //hostReturnCode非全为9或非全为0时表示失败
                    if(success(respCode)){
                        detail.transState = "000000";
                    }else if(success999(respCode)){
                        detail.transState = "999999";
                    }else {
                        detail.transState = respCode;
                    }
                    detail.payInfoCode = detail.transState;
                    detail.transAmt = "";
                }else{
                    detail.respCode ="-1";
                    detail.respInfo = tmpSbMsg.toString();
                }
            }else if (bankResult[0].equals(ConnState.FAIL)) {
                detail.respCode = "0";
                detail.respInfo = bankResult[1];
                detail.reqSeqID = p_req1908.singleDetail.askNumber;
                detail.transState = PaymentState.FAIL_Payment;
                detail.payInfoCode = bankResult[0];
            }else{
                detail.respCode ="-1";
                detail.respInfo = bankResult[1];
                detail.reqSeqID = p_req1908.singleDetail.askNumber;
            }
        }catch (Exception e){
            detail.respCode = "-1";
            detail.respInfo = e.getMessage();
            e.printStackTrace();
        }finally {
            conn.close();
        }
        retAtsSingle.writeRetDetail(detail);
        return retAtsSingle;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    /**
     * 查询支付结果
     * @param p_req1944
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAtsSingle = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        Connection conn= FGBiz.getLocalDbConn();
        try{
            //======拼接报文======
            //拼接请求报文体
            WFCCB01Header header = new WFCCB01Header();
            header.opname="otherAccQry";
            header.serialNo = getQryTransID();
            XmlTextWriter xmlReq = new XmlTextWriter();
            writeReqHeader(xmlReq,header);
            XElement body =new XElement("ReqParam","");
            Map<String, Object> selMap=JDBCHelper.execQuerySingle(conn,SELECTSEQ,new Object[]{p_req1944.askNumber,p_req1944.reqHeader.bankCode});
            if(selMap.size()>0){
                body.addChild(new XElement("orderFlowNo", selMap.get("BANKREQSEQID").toString()));//交易流水号
            }else {
                detail.respCode ="-1";
                detail.respInfo = "交易流水号关联映射异常，请检查";
                retAtsSingle.writeRetDetail(detail);
                return retAtsSingle;
            }
            xmlReq.writeXElement(body);
            xmlReq.writeEndDocument();
            //获取签名数据
            String sign=signnatrue(xmlReq.toXmlString());
            //拼接请求报文
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            header.signedData=sign;
            writeCommonHeader(xmlTextWriter,header);
            xmlTextWriter.directWrite(xmlReq.toXmlString());
            xmlTextWriter.writeEndElement();
            //======拼接报文======
            //发送请求报文
            String[] bankResult = sendToBank(requestBody(header,xmlTextWriter.toXmlString()));
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String respCode = tmpBkReader.getFirstText("/BankData/opRep/hostReturnCode");
                    String respInfo = tmpBkReader.getFirstText("/BankData/opRep/hostErrorMessage");
                    if (success(respCode)) {
                        String state = tmpBkReader.getFirstText("/BankData/opRep/RepParam/state");//交易状态
                        String errorMessage = tmpBkReader.getFirstText("/BankData/opRep/RepParam/errorMessage");//失败原因
                        detail.respCode = "0";
                        detail.respInfo = errorMessage;
                        detail.transState = state;
                        detail.reqSeqID = p_req1944.askNumber;
                        detail.payInfoCode = detail.transState;
                        detail.transAmt = "";
                    }else {
                        detail.respCode = "-1";
                        detail.respInfo = respInfo;
                    }
                }else {
                    detail.respCode = "-1";
                    detail.respInfo = tmpSbMsg.toString();
                }
            }else {
                detail.respCode = "-1";
                detail.respInfo = bankResult[1];
            }
        }catch (Exception e){
            detail.respCode = "-1";
            detail.respInfo = e.getMessage();
            e.printStackTrace();
        }finally {
            conn.close();
        }
        retAtsSingle.writeRetDetail(detail);
        return retAtsSingle;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
